package main

import "fmt"

//断言
//Go语言里面有一个语法，可以直接判断是否是该类型的变量:value,ok=element.(T),这里value就是变量的值
//ok是一个bool类型，element是interface变量，T是断言的类型

// 接口的定义：定义规则，定义规范，定义某种能力
type SayHello interface {
	//这里声明没有实现的方法
	SayHello()
}

// 接口的实现：定义结构体：
type person struct {
	name string
	age  int
}

type chinese struct {
	person
}

type American struct {
	person
}

// 2.只要是自定义数据类型，就可以实现接口，不仅仅是结构体类型
type interger int

func (i interger) SayHello() {
	fmt.Println("say hi", i)
}

// 实现接口的方法
func (ch chinese) SayHello() {
	fmt.Println("你好")
}

// 定义中国人特有的方法
func (ch chinese) niuyangge() {
	fmt.Println("扭秧歌")
}

func (ch American) SayHello() {
	fmt.Println("hi")
}

// 定义一个函数 专门用用来各国人打招呼的打招呼的函数，接受具备SayHello接口能力的变量
func greet(s SayHello) {
	s.SayHello()
	//断言
	//ch, flag := s.(chinese) //看看s是否能转成chinese并且赋值给ch变量 如果成功返回flag为true 否则为false
	//if flag {
	//	ch.niuyangge()
	//}
	if ch, flag := s.(chinese); flag {
		ch.niuyangge()
	} else {
		fmt.Println("美国人不会扭秧歌")
	}

}

func main() {
	c := &chinese{
		person{
			name: "Zeng",
			age:  12,
		},
	}

	a := &American{
		person{
			name: "yu",
			age:  22,
		},
	}

	greet(*c) //传入结构体的值
	greet(*a)

}
